package pers.jason.wppm.workflow.controller;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.DeploymentEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pers.jason.wppm.api.support.ResultView;
import pers.jason.wppm.workflow.entity.DeploymentResult;
import pers.jason.wppm.workflow.entity.ProcessDefinitionResult;
import pers.jason.wppm.workflow.entity.ProcessInstanceResult;
import pers.jason.wppm.workflow.entity.TaskResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: JZH
 * @Date: 2018/11/13 23:28
 * @Description:
 */
@RestController
@RequestMapping("process")
public class ActivitiController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    /* ----------------- 流程定义 ----------------- */

    /**
     * 获取流程定义列表
     * @return
     */
    @GetMapping("define/list")
    public ResultView getProcessDefinitionList() {
        List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
        List<ProcessDefinitionResult> results = new ArrayList<>();
        for(ProcessDefinition processDefinition : processDefinitionList) {
            results.add(new ProcessDefinitionResult((ProcessDefinitionEntity) processDefinition));
        }
        return ResultView.success(results);
    }

    /* ----------------- 流程部署 ----------------- */

    /**
     * 获取流程部署列表
     * @return
     */
    @GetMapping("deployment/list")
    public ResultView getDeploymentList() {
        List<Deployment> deploymentList = repositoryService.createDeploymentQuery().list();
        List<DeploymentResult> results = new ArrayList<>();
        for(Deployment deployment : deploymentList) {
            results.add(new DeploymentResult((DeploymentEntity) deployment));
        }
        return ResultView.success(results);
    }

    /* ----------------- 流程实例 ----------------- */

    /**
     * 获取流程实例列表
     * @return
     */
    @GetMapping("instance/list")
    public ResultView getProcessInstanceList() {
        List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().orderByProcessInstanceId().desc().list();
        List<ProcessInstanceResult> results = new ArrayList<>();
        for(ProcessInstance processInstance : processInstanceList) {
            results.add(new ProcessInstanceResult(processInstance));
        }
        return ResultView.success(results);
    }



    /* ----------------- 查询任务 ----------------- */

    /**
     * 获取任务列表
     * @return
     */
    @GetMapping("task/list")
    public ResultView getTaskList() {
        List<Task> taskList = taskService.createTaskQuery().active().list();
        List<TaskResult> results = new ArrayList<>();
        for(Task task : taskList) {
            results.add(new TaskResult(task));
        }
        return ResultView.success(results);
    }

    /**
     * 获取用户的代办任务
     * 获取已签收、单独分配给自己、待签收的任务
     * @param userId
     * @return
     */
    @GetMapping("tasks/user/{userId}")
    public ResultView getTasksByUser(@PathVariable("userId") String userId) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(userId).list();
        List<TaskResult> results = new ArrayList<>();
        for(Task task : tasks) {
            results.add(new TaskResult(task));
        }
        return ResultView.success(results);
    }

    /**
     * 获取待签收的任务
     * 包括分配的候选人和候选组
     * @return
     */
    @GetMapping("tasks/nosign/user/{userId}")
    public ResultView getTasksNotSignInByUser(@PathVariable("userId") String userId) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("005513").list();
        List<TaskResult> results = new ArrayList<>();
        for(Task task : tasks) {
            results.add(new TaskResult(task));
        }
        return ResultView.success(results);
    }

    @PutMapping("task/{taskId}")
    public ResultView signInTask(@PathVariable("taskId") String taskId) {
        taskService.claim(taskId, "005513");
        return ResultView.success();
    }

    /**
     * 获取用户在某个流程实例下的任务
     * @param processInstanceId
     * @param userId
     * @return
     */
    @GetMapping("tasks/{processInstanceId}/{userId}")
    public ResultView getTasksByProcessInstanceAndUser(@PathVariable("processInstanceId") String processInstanceId, @PathVariable("userId") String userId) {
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).taskCandidateOrAssigned(userId).active().list();
        List<TaskResult> results = new ArrayList<>();
        for(Task task : tasks) {
            results.add(new TaskResult(task));
        }
        return ResultView.success(results);
    }

    /* ----------------- 用户操作 ----------------- */

    /**
     * 根据流程定义key创建并启动流程实例
     * @param definitionKey
     */
    @PostMapping("start/{definitionKey}")
    public ResultView startProcess(@PathVariable("definitionKey") String definitionKey) {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(definitionKey);
        return ResultView.success(new ProcessInstanceResult(processInstance));
    }

    /**
     * 启动并同时完成第一个环节
     * @return
     */
    @PostMapping("start/nofirst/{definitionKey}")
    public ResultView startProcessAndFinishNode(@PathVariable("definitionKey") String definitionKey, String auditors) {
        logger.info("进入controller...");
        logger.info("开始创建流程实例...");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(definitionKey);
        logger.info("创建完成流程实例...");
        logger.info("获取第一个任务...");
        List<TaskResult> tasks = (List<TaskResult>) getTasksByProcessInstanceAndUser(processInstance.getId(), "003571").getResult();
        TaskResult taskResult = tasks.get(0);
        Task t = taskService.createTaskQuery().taskId(taskResult.getId()).singleResult();
        Map<String, Object> params = new HashMap<>();
        params.put(processInstance.getId()+":" + "需求提出部门领导评审", auditors);
        logger.info("获取到第一个任务...");
        logger.info("开始完成第一个任务...");
        taskService.complete(t.getId(), params);
        logger.info("完成第一个任务...");
        return ResultView.success();
    }


}
